package com.mezz.bones.framework.websocket.service;

import cn.hutool.core.util.StrUtil;
import jakarta.websocket.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@Service
public class WebSocketSessionManager {
    private static final Logger log = LoggerFactory.getLogger(WebSocketSessionManager.class);

    /**
     * key - userId
     * value - 多设备连接
     */
    private final ConcurrentHashMap<String, CopyOnWriteArrayList<Session>> webSocketMap = new ConcurrentHashMap<>();

    public void addSession(String userId, Session session) {
        CopyOnWriteArrayList<Session> sessions = webSocketMap.computeIfAbsent(userId, k -> new CopyOnWriteArrayList<>());
        sessions.add(session);
        log.info("Session {} added for userId: {}. Total sessions for this id: {}", session.getId(), userId, sessions.size());
    }

    public void removeSession(String userId, Session sessionToRemove) {
        CopyOnWriteArrayList<Session> sessions = webSocketMap.get(userId);
        if (sessions != null) {
            boolean removed = sessions.remove(sessionToRemove);
            if (removed) {
                log.info("Session {} removed for userId: {}. Remaining sessions for this id: {}", sessionToRemove.getId(), userId, sessions.size());
            }

            if (sessions.isEmpty()) {
                webSocketMap.remove(userId);
                log.info("userId: {} removed from map as no more sessions are active.", userId);
            }
        }
    }

    public List<Session> getSessions(String userId) {
        return webSocketMap.get(userId);
    }

    public void sendMessage(String userId, String message) {
        CopyOnWriteArrayList<Session> sessions = webSocketMap.get(userId);
        if (sessions != null && !sessions.isEmpty()) {
            log.debug("Sending message to {} sessions for userId {}: {}", sessions.size(), userId, message);
            for (Session session : sessions) {
                sendMessage(session, message);
            }
        } else {
            log.warn("No active sessions found for userId: {} to send message: {}", userId, message);
        }
    }

    public void sendMessage(Session session, String message) {
        if (session != null && session.isOpen()) {
            try {
                session.getAsyncRemote().sendText(message);
                log.debug("Message sent to session {}: {}", session.getId(), message);
            } catch (Exception e) {
                log.error("Error sending message to session {}: {}", session.getId(), e.getMessage(), e);
            }
        } else {
            log.warn("Session is null or closed, cannot send message: {}", message);
        }
    }

    public void broadcastMessage(String message) {
        log.debug("Broadcasting message to all {} userIds: {}", webSocketMap.size(), message);
        webSocketMap.values().forEach(sessions -> {
            for (Session session : sessions) {
                sendMessage(session, message);
            }
        });
    }

    /**
     * 获取指定userId的当前连接数
     * @param userId 连接ID
     * @return 当前连接数
     */
    public int getSessionCount(String userId) {
        if (StrUtil.isBlank(userId)) {
            return 0;
        }

        List<Session> sessions = webSocketMap.get(userId);
        return sessions != null ? sessions.size() : 0;
    }
}